<?php

namespace app\service;

use app\model\Article as ArticleModel;
use think\facade\Db;

class ArticleService
{
    protected $model;
    protected $categoryService;

    public function __construct(){
        $this->model = app()->make(ArticleModel::class);
        $this->categoryService = app()->make(CategoryService::class);
    }

    /**
     * @param $where
     * @param int $pageSize
     * @return ArticleModel[]|array|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function queryListByPage($where, $pageSize = 15)
    {
        $objectList = $this->model->order('created_time desc')->where($where)->paginate($pageSize);
        $list = $objectList->toArray();
        $list['page'] = $objectList->render();
        $list['data'] = $this->fillCategory($list['data']);
        $list['data'] = $this->fillTags($list['data']);
        return $list;
    }

    /**
     * @param $where
     * @param int $limit
     * @param string $order
     * @param bool $needCategory
     * @param bool $needTag
     * @return ArticleModel[]|array|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function queryList($where, $limit = 30, $order = 'created_time desc', $needCategory = false, $needTag = false)
    {
        $list = $this->model->order($order)->where($where)->limit($limit)->select();
        if (empty($list)) {
            return array();
        }
        if ($needCategory) {
            $list = $this->fillCategory($list->toArray());
        }
        if ($needTag) {
            $list = $this->fillTags($list->toArray());
        }
        return $list;
    }

    /**
     * 补充分类
     *
     * @param $list
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function fillCategory($list) {
        $cidArr = array_column($list, 'cid');
        $categoryWhere['id'] = $cidArr;
        $categoryList = $this->categoryService->queryListByWhere($categoryWhere);
        $categoryList = array_change_key($categoryList->toArray(), 'id');
        foreach ($list as $key=>$item) {
            if (empty($categoryList[$item['cid']])) {
                continue;
            }
            $category = $categoryList[$item['cid']];
            $item['categoryName'] = $category['name'];
            $list[$key] = $item;
        }
        return $list;
    }
    /**
     * 补充标签
     *
     * @param $list
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function fillTags($list) {
        $idArr = array_column($list, 'id');
        $tagList = $this->queryTagsByIds($idArr);
        $tagList = array_group_key($tagList->toArray(), 'aid');
        foreach ($list as $key=>$item) {
            if (isset($tagList[$item['id']])){
                $item['tagArr'] = $tagList[$item['id']];
            }
            $list[$key] = $item;
        }
        return $list;
    }

    /**
     * @param int $id
     * @return ArticleModel|array|mixed|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function queryDetail(int $id){
        $article = $this->model->where('id', $id)->find();
        $article['content'] = str_replace("'","\"", $article['content']);
        return $article;
    }

    /**
     * 更新数量
     *
     * @param $field
     * @param $id
     * @return bool
     * @throws \think\db\exception\DbException
     */
    public function updateCount($field, $id): bool
    {
        return Db::table("pre_article")->where('id', $id)->inc($field)->update();
    }


    /**
     * @param $tagId
     * @return array|\think\Collection|Db[]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function queryListByTag($tagId)
    {
        $list = Db::table("pre_article")->alias("a")->join('pre_tag_article ta','a.id=ta.aid')->where(array('ta.tid'=>$tagId))->field("a.*, ta.id as tid")->order('a.created_time desc')->select();
        if (empty($list)) {
            return array();
        }
        $cidArr = array_column($list->toArray(), 'cid');
        $categoryList = $this->categoryService->queryListByIdArr($cidArr);
        $categoryList = array_change_key($categoryList->toArray(), 'id');
        $idArr = array_column($list->toArray(), 'id');
        $tagList = $this->queryTagsByIds($idArr);
        $tagList = array_group_key($tagList->toArray(), 'aid');
        foreach ($list as $key=>$item) {
            if (empty($categoryList[$item['cid']])) {
                continue;
            }
            $category = $categoryList[$item['cid']];
            $item['categoryName'] = $category['name'];
            if (isset($tagList[$item['id']])){
                $item['tagArr'] = $tagList[$item['id']];
            }
            $list[$key] = $item;
        }
        return $list;
    }

    /**
     * 根据条件查询标签
     *
     * @param $idArr
     * @return array|\think\Collection|Db[]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function queryTagsByIds($idArr) {
        $list = Db::table("pre_tag_article")->alias("ta")->join('pre_tag t','ta.tid=t.id')->whereIn('ta.aid',$idArr)->field("ta.aid,t.*")->select();
        if (empty($list)) {
            return array();
        }
        return $list;
    }
}